home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / syszm.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  16KB  |  662 lines

  1. /*
  2.  * *       syszm.c * * External protocol handlers.
  3.  */
  4. /*
  5.  * *       history * * 89Aug14 HAW  Rewritten for versatility. * 88Nov13 HAW
  6.  * Created.
  7.  */
  8. #define SYSTEM_DEPENDENT
  9. #include "ctdl.h"
  10. #include "dos.h"
  11.  
  12. int       Jsystem(char *);
  13. long      Do_Zmodem(char *files, int direction);
  14.                          /** returns TRUE if error **/
  15. /**
  16.    Contents
  17.  AddExternProtocolOptions() to system menus
  18.  AddNames()         Allows building strings of names
  19.  AddOurOpts()       add  options to a menu list.
  20.  DoesNumerous()     BATCH checking function.
  21.  EatExtMessage()    Send a bundle of messages
  22.  EatProtocol()      Eats a protocol definition line.
  23.  ExternalProtocol() Handles all external protocols
  24.  FindProtocolCode() finds a protocol value for id purposes
  25.  FindProtoName()    returns the name of the ext protocol.
  26.  FindProtocol()     work function for finding things.
  27.  InitProtocols()   initializes external protocols
  28. **/
  29. char      MakeCmdLine(char *, char *, char *miscdata, int len);
  30. void      AddName(DirEntry *);
  31. int       ExternalProtocol(int, char, char *, char *, char);
  32. typedef struct
  33.   {
  34.     char      Selector,
  35.              *Name,
  36.               Down,
  37.              *CmdLine,
  38.              *Display,
  39.               Many;
  40.     int       ProtVal;
  41.  
  42.   }
  43. PROTOCOL;
  44. char      GetSizes = FALSE;
  45. int       ExCount = 4;
  46. void     *EatProtocol(char *line);
  47. void     *FindProtocol(PROTOCOL *, int *);
  48. void      InitProtocols(void);
  49. static SListBase ExtProtocols =
  50. {
  51.   NULL, FindProtocol, NULL, NULL, EatProtocol
  52.  
  53. };
  54. static char FindCode = FALSE;
  55. extern CONFIG cfg;
  56. extern MessageBuffer msgBuf;
  57. extern aRoom roomBuf;
  58. extern char loggedIn;
  59. extern int SystemPort;
  60. extern char onConsole;              /*
  61.  
  62.                                              * Where we get stuff from
  63.                                              */
  64. extern logBuffer logBuf;
  65. char      AddStringToMCL(char *target, char *source, int len);
  66. void      EnglishWork(char *target, char Ups);
  67. char      cmdline[125];             /* we have a limit  */
  68. /*
  69.  * * InitProtocols() * * This function initializes external protocols.
  70.  */
  71. void
  72. InitProtocols()
  73. {
  74.   SYS_FILE  fn;
  75.  
  76.   makeSysName(fn, "ctdlprot.sys", &cfg.roomArea);
  77.   MakeList(&ExtProtocols, fn, NULL);
  78.  
  79. }
  80. /**
  81.   EatProtocol()
  82. This function eats a protocol line.
  83.   Format:
  84.  [selector] [1/M] [name] [u/d] [command line]
  85.  [selector] [I]   [name] [u/d] [Internal Zmodem]
  86. **/
  87. void     *
  88. EatProtocol(char *line)
  89. {
  90.   PROTOCOL *temp;
  91.   char     *c,
  92.            *err;
  93.  
  94.   if (cfg.BoolFlags.debug)
  95.     splitF(NULL, "External:%s\n", line);
  96.   err = line;
  97.   NormStr(line);
  98.   if (strLen(line) == 0)
  99.     return NULL;
  100.   temp = GetDynamic(sizeof *temp);
  101.   temp->Selector = line[0];
  102.   line += 2;
  103.   temp->Many = toUpper(line[0]);
  104.   /**
  105.      Could be "1" or "M"
  106.   **/
  107.   switch (temp->Many)
  108.     {
  109.         case '1':       /*
  110.                          * Single file, external protocol handler
  111.                          */
  112.         case 'M':       /*
  113.                          * Multiple files, external protocol handler
  114.                          */
  115.         case 'I':       /*
  116.                          * Internal Zmodem
  117.                         */
  118.           break;
  119.         default:
  120.           splitF(NULL, "Invalid Protocol in CTDLPROT.SYS\n%s\n", err);
  121.  
  122.     }
  123.   line += 2;
  124.   if ((c = strchr(line, ' ')) != NULL)
  125.     *c = 0;
  126.   temp->Name = strdup(line);
  127.   line = lbyte(line) + 1;
  128.   temp->Down = (toUpper(line[0]) == 'D') ? TRUE : FALSE;
  129.   line += 2;
  130.   temp->CmdLine = strdup(line);
  131.   temp->ProtVal = ExCount++;
  132.   sPrintf(cmdline, "%s%c\b%s", NTERM, temp->Selector, temp->Name);
  133.   temp->Display = strdup(cmdline);
  134.   return temp;
  135.  
  136. }
  137. /**
  138.  ExternalProtocol()
  139.   This function handles external protocols.  It
  140.   also checks for external message uploads/downloads.
  141. **/
  142. int
  143. ExternalProtocol(int protocol, char upload, char *mask, char *phrase,
  144.                      char Move)
  145. {
  146.   PROTOCOL *Prot;
  147.   int       toReturn;
  148.   extern long byteRate;
  149.   extern int SystemPort;
  150.   SpecialMessage("Status:External Protocol");
  151.   if (cfg.BoolFlags.debug)
  152.     {
  153.         splitF(NULL, "ExternalProtocol(%d,%s,%s,%s,%s)\n", protocol,
  154.         (upload ? "TRUE" : "FALSE"), mask, phrase, (Move ? "TRUE" : "FALSE"));
  155.  
  156.     };
  157.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  158.     {
  159.         if (cfg.BoolFlags.debug) splitF(NULL, "SearchList failed to find Protocol\n");
  160.         return TRAN_FAILURE;
  161.  
  162.     };
  163.   if (Move && !setSpace(&roomBuf))
  164.     {
  165.         if (cfg.BoolFlags.debug)   splitF(NULL, "SetSpace Failed\n");
  166.         return TRAN_FAILURE;
  167.  
  168.     };
  169.   if (!upload)
  170.     {
  171.         msgBuf.mbtext[0] = 0;
  172.         wildCard(AddName, mask, FALSE, phrase, TRUE);
  173.  
  174.     }
  175.   else
  176.     strCpy(msgBuf.mbtext, mask);
  177.   if (Prot->Many == '1' || Prot->Many == 'M')   /*
  178.                                                                  * old style
  179.                                                                  */
  180.     {
  181.         if (cfg.BoolFlags.debug) splitF(NULL, "Making external command line\n");
  182.         if (!MakeCmdLine(cmdline, Prot->CmdLine, msgBuf.mbtext, sizeof cmdline - 1))
  183.           {
  184.             if (strchr(mask, '>') != NULL || strchr(mask, '<') != NULL)
  185.                 {
  186.                   if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
  187.                   Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
  188.                   if (Move)     homeSpace();
  189.                   return TRAN_FAILURE;
  190.  
  191.                 }
  192.             else if (!MakeCmdLine(cmdline, Prot->CmdLine, mask, sizeof cmdline - 1))
  193.                 {
  194.                   if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
  195.                   Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
  196.                   if (Move)  homeSpace();
  197.                   return TRAN_FAILURE;
  198.  
  199.                 }
  200.  
  201.           };
  202.  
  203.     };
  204.   if (!upload)
  205.     fileMessage(FL_START, mask, TRUE, protocol, 0l);
  206.   if (loggedIn)
  207.     printf("\n(%s)\n %s", logBuf.lbname, cmdline);
  208.   if (Prot->Many == '1' || Prot->Many == 'M')   /* old style */
  209.     {
  210.         Jsystem(cmdline);
  211.  
  212.     }
  213.   else
  214.  
  215. /**
  216.    Internal Zmodem
  217.  
  218. **/
  219.     {
  220.  
  221.     if( Do_Zmodem(msgBuf.mbtext, upload) )
  222.        return TRAN_FAILURE ;
  223.  
  224.  
  225.     };
  226.   if (!upload)
  227.     {
  228.         GetSizes = TRUE;
  229.         ExCount = 0;
  230.         strCpy(msgBuf.mbtext, "   ");
  231.         (void)wildCard(AddName, mask, Move, phrase, TRUE);
  232.         GetSizes = FALSE;
  233.         if (Move)         homeSpace();
  234.         fileMessage(FL_EX_END, mask, TRUE, protocol, 0l         /*
  235.                                                                                  * filled in
  236.                                                                                  */ );
  237.         toReturn = TRAN_SUCCESS;
  238.   /* if( realCount > 0 )transRecDown(mask, realCount); */
  239.  
  240.     }
  241.   else
  242.     {
  243.         toReturn = ((strcmp(mask, "msg") == 0) || (access(mask, 0) == 0))
  244.           ? TRAN_SUCCESS : TRAN_FAILURE;
  245.  
  246.     }
  247.   return toReturn;
  248.  
  249. }
  250. UNS_16    intrates[] =
  251. {
  252.   30, 120, 240, 480, 960, 1440, 1920, 3840, 5760
  253.  
  254. };
  255.  
  256. /*
  257.  * * MakeCmdLine() * * This function creates a command line, including
  258.  * supported substitution * parameters.  This should be detailed in this
  259.  * comment but isn't.
  260.  */
  261. char
  262. MakeCmdLine(char *target, char *source, char *miscdata, int len)
  263. {
  264.   extern int thisLog;               /*
  265.  
  266.                                              * entry currently in logBuf
  267.                                              */
  268.   char     *c,
  269.            *temp,
  270.             NoOverflow = TRUE;
  271.   int       i;
  272.   long the_bps;
  273.   for (i = 0, c = source; *c; c++)
  274.     {
  275.         if (i > len - 2)
  276.           {
  277.             NoOverflow = FALSE;
  278.             break;
  279.  
  280.           }
  281.         if (*c == '%')
  282.           {
  283.             target[i] = 0;
  284.             c++;
  285.             switch (*c)
  286.                 {
  287.                   case 'a':     /* baud rate */
  288.                     if (onConsole)
  289.                         sPrintf(lbyte(target), "%d", 0);
  290.                     else
  291.                         sPrintf(lbyte(target), "%ld",
  292.                                   (cfg.DepData.LockPort != -1) ?
  293.                             (long)(intrates[cfg.DepData.LockPort] * 10) : byteRate * 10);
  294.                     break;
  295.                   case 'b':     /* bps */
  296.                     if( onConsole )
  297.                       {
  298.                       the_bps = 0;
  299.                       }
  300.                     else if( cfg.DepData.LockPort == -1 )
  301.                       {
  302.                       the_bps = byteRate;
  303.                       }
  304.                     else
  305.                       {
  306.                       the_bps = (long)(intrates[cfg.DepData.LockPort]);
  307.                       };
  308.                     sPrintf(lbyte(target), "%ld", the_bps);
  309.                     break;
  310.                   case 'c':     /* port # */
  311.                     sPrintf(lbyte(target), "%d", SystemPort);
  312.                     break;
  313.                   case 'e':     /* log number of the user */
  314.                     sPrintf(lbyte(target), "%d", thisLog);
  315.                     break;
  316.                   case 'f':     /* ANSI code of the user  */
  317.                     sPrintf(lbyte(target), "0");
  318.                     break;
  319.                   case 'g':     /* file mask */
  320.                     NoOverflow = AddStringToMCL(target, miscdata, len);
  321.                     break;
  322.                   case 'h':
  323.                     if (byteRate != 0)
  324.                         sPrintf(lbyte(target), "COM%d", SystemPort);
  325.                     else
  326.                         strCat(target, "LOCAL");
  327.                     break;
  328.                   case 'i':
  329.                     NoOverflow = AddStringToMCL(target, roomBuf.rbname, len);
  330.                     break;
  331.                   case 'j':
  332.                     if ((temp = FindDirName(roomBuf.rbArea)) != NULL)
  333.                         NoOverflow = AddStringToMCL(target, temp, len);
  334.                     break;
  335.                   case 'k':
  336.                     sPrintf(lbyte(target), "%d", logBuf.lbwidth);
  337.                     break;
  338.                   case 'd':
  339.                     strCat(target, logBuf.lbname);
  340.                     break;
  341.  
  342.                 }
  343.             while (target[i])
  344.                 i++;
  345.  
  346.           }
  347.         else
  348.           target[i++] = *c;
  349.  
  350.     }
  351.   target[i] = 0;
  352.   if (cfg.BoolFlags.debug)
  353.     splitF(NULL, "Command Line is %d long\n", strlen(target));
  354.   return NoOverflow;
  355.  
  356. }
  357. /*
  358.  * * AddStringToMCL() * * This adds a string as needed, I guess.
  359.  */
  360. char
  361. AddStringToMCL(char *target, char *source, int len)
  362. {
  363.   if (strlen(source) + strlen(target) < len - 2)
  364.     {
  365.         strCat(target, source);
  366.         return TRUE;
  367.  
  368.     }
  369.   else
  370.     {
  371.         strncpy(lbyte(target), source, len - strlen(target) - 1);
  372.         target[len - 1] = 0;
  373.         return FALSE;
  374.  
  375.     }
  376.  
  377. }
  378. static char **TheOpts,
  379.           IsUpload;
  380.  
  381. /*
  382.  * * AddExternProtocolOptions() * * This function adds external protocol
  383.  * options to system menus.
  384.  */
  385. void
  386. AddExternProtocolOptions(char **Opts, char upload)
  387. {
  388.   void      AddOurOpts();
  389.  
  390.   TheOpts = Opts;
  391.   IsUpload = upload;
  392.   RunList(&ExtProtocols, AddOurOpts);
  393.  
  394. }
  395. /*
  396.  * * AddOurOpts() * * This function does the actual work of adding an option
  397.  * to a menu list.
  398.  */
  399. void
  400. AddOurOpts(PROTOCOL * d)
  401. {
  402.   if ((d->Down && IsUpload) ||
  403.         (!d->Down && !IsUpload))
  404.     return;
  405.   ExtraOption(TheOpts, d->Display);
  406.  
  407. }
  408. /*
  409.  * * FindProtocolCode() * * This function finds a protocol value for id
  410.  * purposes.
  411.  */
  412. int
  413. FindProtocolCode(int c, char upload)
  414. {
  415.   PROTOCOL *Prot;
  416.  
  417.   FindCode = TRUE;
  418.   IsUpload = upload;
  419.   if (isalpha(c))
  420.     c = toUpper(c);
  421.   Prot = SearchList(&ExtProtocols, &c);
  422.   FindCode = FALSE;
  423.   if (Prot == NULL)
  424.     return -1;
  425.   return Prot->ProtVal;
  426.  
  427. }
  428. /*
  429.  * * FindProtoName() * * This function returns the name of the external
  430.  * protocol.
  431.  */
  432. char     *
  433. FindProtoName(int protocol)
  434. {
  435.   PROTOCOL *Prot;
  436.  
  437.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  438.     return NULL;
  439.   return Prot->Name;
  440.  
  441. }
  442. /*
  443.  * * FindProtocol() * * This work function helps find a protocol in a list.
  444.  */
  445. void     *
  446. FindProtocol(PROTOCOL * d, int *val)
  447. {
  448.   if (FindCode)
  449.     {
  450.         if (*val == d->Selector && IsUpload != d->Down)
  451.           return d;
  452.  
  453.     }
  454.   else if (*val == d->ProtVal)
  455.     return d;
  456.   return NULL;
  457.  
  458. }
  459. /*
  460.  * * DoesNumerous() * * Does this protocol support BATCH downloads?
  461.  */
  462. char
  463. DoesNumerous(int protocol)
  464. {
  465.   PROTOCOL *Prot;
  466.  
  467.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  468.     return FALSE;
  469.   return (char) (Prot->Many == 'M' || Prot->Many == 'I');
  470.  
  471. }
  472. /*
  473.  * * EatExtMessage() * * This function eat a message upload using an
  474.  * external protocol.  It returns * TRAN_SUCCESS on success, TRAN_FAILURE
  475.  * otherwise.
  476.  */
  477. int
  478. EatExtMessage(int protocol)
  479. {
  480.   struct FileInfoBlock *info;
  481.   int       result;
  482.   extern char TDirBuffer[];
  483.   char      dir[80];
  484.  
  485.   MakeTempDir();
  486.   if ((result = ExternalProtocol(protocol, TRUE, "msg", "", FALSE)) == TRAN_SUCCESS)
  487.     {
  488.         chdir(TDirBuffer);
  489.         info = (struct FileInfoBlock *) calloc(1, sizeof(struct FileInfoBlock));
  490.  
  491.         if (info == NULL)
  492.           {
  493.             splitF(NULL, "Unable to get memory for info buffer(syszm)\n");
  494.  
  495.           }
  496.         else
  497.           {
  498.             result = dfind(info, ALL_FILES, 0); /*
  499.                                                                  * get the filename
  500.                                                                  */
  501.             if (result == 0)
  502.                 {
  503.                   if (cfg.BoolFlags.debug)
  504.                     splitF(NULL, "Ingesting:", info->fib_FileName);
  505.                   ingestFile(info->fib_FileName, &msgBuf);
  506.                   unlink(info->fib_FileName);
  507.  
  508.                 }
  509.             else
  510.                 splitF(NULL, "No file found!(syszm)\n");
  511.             free(info);
  512.  
  513.           };
  514.  
  515.     }
  516.   else
  517.     {
  518.         splitF(NULL, "Transfer failed(syszm)\n");
  519.         if (cfg.BoolFlags.debug)
  520.           {
  521.             (void) getcd(0, dir);
  522.             splitF(NULL, " Dir:%s\n Other:%s\n", dir, TDirBuffer);
  523.  
  524.           };
  525.  
  526.     };
  527.   homeSpace();
  528.   rmdir(TDirBuffer);
  529.   return result;
  530.  
  531. }
  532. /*
  533.  * * AddName() * * This function is used in conjunction with wildCard to
  534.  * generate a list * of names, optionally with filesizes in parenthesis
  535.  * 4/line.  This is used * to generate a command line or a report in
  536.  * FILELOG.SYS.
  537.  */
  538. void
  539. AddName(DirEntry * file)
  540. {
  541.   if (strLen(msgBuf.mbtext) > MAXTEXT - 200)
  542.     {
  543.         if (GetSizes)
  544.           strCat(msgBuf.mbtext, ".");
  545.  
  546.     }
  547.   else
  548.     {
  549.         sPrintf(lbyte(msgBuf.mbtext), " %s", file->unambig);
  550.         if (GetSizes)
  551.           {
  552.             sPrintf(lbyte(msgBuf.mbtext), " (%ld)", file->FileSize);
  553.             if (++ExCount == 4)
  554.                 {
  555.                   strCat(msgBuf.mbtext, "\n   ");
  556.                   ExCount = 0;
  557.  
  558.                 }
  559.  
  560.           }
  561.  
  562.     }
  563.  
  564. }
  565. static char *msgText,
  566.           UpsOnly;
  567.  
  568. /*
  569.  * * UpProtsEnglish() * * This generates a list of upload protocol names.
  570.  * It is used by the help * system.
  571.  */
  572. void
  573. UpProtsEnglish(char *target)
  574. {
  575.   EnglishWork(target, TRUE);
  576.  
  577. }
  578. /*
  579.  * * DownProtsEnglish() * * This function generates a list of download
  580.  * protocol names for use by the * help system.
  581.  */
  582. void
  583. DownProtsEnglish(char *target)
  584. {
  585.   EnglishWork(target, FALSE);
  586.  
  587. }
  588. /*
  589.  * * EnglishWork() * * This function does the real work of generating names.
  590.  */
  591. void      List_Names(PROTOCOL *);
  592. void
  593. EnglishWork(char *target, char Ups)
  594. {
  595.   char     *c;
  596.  
  597.   target[0] = 0;
  598.   msgText = target;
  599.   UpsOnly = Ups;
  600.   RunList(&ExtProtocols, List_Names);
  601.   if ((c = strrchr(target, ',')) == NULL)
  602.     strCpy(target, "None.");
  603.   else
  604.     strCpy(c, ".");
  605.  
  606. }
  607. /*
  608.  * * List_Names() * * This function helps build the list of protocols
  609.  * available.
  610.  */
  611. void
  612. List_Names(PROTOCOL * d)
  613. {
  614.   char     *c;
  615.  
  616.   if (UpsOnly != d->Down)
  617.     {
  618.         c = lbyte(msgText);
  619.         sPrintf(c, "<%c>%s, ", d->Selector, (d->Selector == d->Name[0]) ?
  620.                   d->Name + 1 : d->Name);
  621.  
  622.     }
  623.  
  624. }
  625. /*
  626.  * * ExternalTransfer() * * This function is used by the network for
  627.  * external protocol transfers.
  628.  */
  629. char
  630. ExternalTransfer(int protocol, char *filename)
  631. {
  632.   PROTOCOL *Prot;
  633.   char     *name,
  634.            *fn;
  635.  
  636.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  637.     return FALSE;
  638.   fn = strdup(filename);
  639.   if ((name = strrchr(fn, '\\')) != NULL)
  640.     {
  641.         *name++ = 0;
  642.         chdir(fn);
  643.  
  644.     }
  645.   else
  646.     {
  647.         name = fn;
  648.  
  649.     }
  650.   if (!MakeCmdLine(cmdline, Prot->CmdLine, name, sizeof cmdline - 1))
  651.     {
  652.         free(fn);
  653.         return FALSE;
  654.  
  655.     }
  656.   Jsystem(cmdline);
  657.   free(fn);
  658.   homeSpace();
  659.   return TRUE;
  660.  
  661. }
  662.